{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Drawing Labels on Samples\n",
    "\n",
    "This recipe demonstrates how to use FiftyOne to render annotated versions of [samples](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html#samples) with their [label field(s)](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html#labels) overlaid."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Requirements\n",
    "\n",
    "In this recipe we'll use the [FiftyOne Dataset Zoo](https://voxel51.com/docs/fiftyone/user_guide/dataset_creation/zoo_datasets.html) to download some labeled datasets to use as sample data for drawing labels.\n",
    "\n",
    "Behind the scenes, FiftyOne uses either the\n",
    "[TensorFlow Datasets](https://www.tensorflow.org/datasets) or\n",
    "[TorchVision Datasets](https://pytorch.org/docs/stable/torchvision/datasets.html) libraries to wrangle the datasets, depending on which ML library you have installed.\n",
    "\n",
    "You can, for example, install PyTorch as follows (we'll also need `pycocotools` to load the COCO dataset, in particular):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Modify as necessary (e.g., GPU install). See https://pytorch.org for options\n",
    "!pip install torch\n",
    "!pip install torchvision\n",
    "\n",
    "!pip install pycocotools"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Drawing COCO detections\n",
    "\n",
    "You can download the validation split of the COCO-2017 dataset to `~/fiftyone/coco-2017/validation` by running the following command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Split 'validation' already downloaded\r\n"
     ]
    }
   ],
   "source": [
    "!fiftyone zoo download coco-2017 --splits validation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's load the dataset, extract a [DatasetView](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html#datasetviews) that contains 100 images from the dataset, and render them as annotated images with their ground truth labels overlaid:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Split 'validation' already downloaded\n",
      "Loading 'coco-2017' split 'validation'\n",
      " 100% |█████| 5000/5000 [14.8s elapsed, 0s remaining, 339.4 samples/s]      \n",
      "Writing annotated images to '/tmp/fiftyone/draw_labels/coco-2017-validation-anno'\n",
      " 100% |███████| 100/100 [7.3s elapsed, 0s remaining, 11.9 samples/s]        \n",
      "Annotation complete\n"
     ]
    }
   ],
   "source": [
    "import fiftyone as fo\n",
    "import fiftyone.zoo as foz\n",
    "import fiftyone.utils.annotations as foua\n",
    "\n",
    "# Directory to write the output annotations\n",
    "anno_dir = \"/tmp/fiftyone/draw_labels/coco-2017-validation-anno\"\n",
    "\n",
    "# Load the validation split of the COCO-2017 dataset\n",
    "dataset = foz.load_zoo_dataset(\"coco-2017\", split=\"validation\")\n",
    "\n",
    "# Extract some samples\n",
    "view = dataset.limit(100)\n",
    "\n",
    "#\n",
    "# You can customize the look-and-feel of the annotations\n",
    "# For more information, see:\n",
    "# https://voxel51.com/docs/fiftyone/user_guide/draw_labels.html#customizing-annotation-rendering\n",
    "#\n",
    "annotation_config = foua.AnnotationConfig({\n",
    "    \"per_object_label_colors\": True\n",
    "})\n",
    "\n",
    "# Render the labels\n",
    "print(\"Writing annotated images to '%s'\" % anno_dir)\n",
    "view.draw_labels(anno_dir, annotation_config=annotation_config)\n",
    "print(\"Annotation complete\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's list the output directory to verify that the annotations have been generated:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total 51976\r\n",
      "drwxr-xr-x  202 Brian  wheel   6.3K Jul 27 18:36 .\r\n",
      "drwxr-xr-x    5 Brian  wheel   160B Jul 27 15:59 ..\r\n",
      "-rw-r--r--    1 Brian  wheel   115K Jul 27 18:36 000001-2.jpg\r\n",
      "-rw-r--r--@   1 Brian  wheel   116K Jul 27 12:51 000001.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel   243K Jul 27 18:36 000002-2.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel   243K Jul 27 12:51 000002.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel   177K Jul 27 18:36 000003-2.jpg\r\n",
      "-rw-r--r--@   1 Brian  wheel   177K Jul 27 12:51 000003.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel   101K Jul 27 18:36 000004-2.jpg\r\n"
     ]
    }
   ],
   "source": [
    "!ls -lah /tmp/fiftyone/draw_labels/coco-2017-validation-anno | head"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's an example of an annotated image that was generated:\n",
    "\n",
    "![coco-2017-annotated](images/draw_labels_coco2017.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Drawing Caltech 101 classifications\n",
    "\n",
    "You can download the test split of the Caltech 101 dataset to `~/fiftyone/caltech101/test` by running the following command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Split 'test' already downloaded\n"
     ]
    }
   ],
   "source": [
    "!fiftyone zoo download caltech101 --splits test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's load the dataset, extract a [DatasetView](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html#datasetviews) that contains 100 images from the dataset, and render them as annotated images with their ground truth labels overlaid:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Split 'test' already downloaded\n",
      "Loading 'caltech101' split 'test'\n",
      " 100% |█████| 9145/9145 [4.8s elapsed, 0s remaining, 1.9K samples/s]      \n",
      "Writing annotated images to '/tmp/fiftyone/draw_labels/caltech101-test-anno'\n",
      " 100% |███████| 100/100 [2.6s elapsed, 0s remaining, 37.4 samples/s]        \n",
      "Annotation complete\n"
     ]
    }
   ],
   "source": [
    "import fiftyone as fo\n",
    "import fiftyone.zoo as foz\n",
    "import fiftyone.utils.annotations as foua\n",
    "\n",
    "# Directory to write the output annotations\n",
    "anno_dir = \"/tmp/fiftyone/draw_labels/caltech101-test-anno\"\n",
    "\n",
    "# Load the test split of the Caltech 101 dataset\n",
    "dataset = foz.load_zoo_dataset(\"caltech101\", split=\"test\")\n",
    "\n",
    "# Extract some samples\n",
    "view = dataset.limit(100)\n",
    "\n",
    "#\n",
    "# You can customize the look-and-feel of the annotations\n",
    "# For more information, see:\n",
    "# https://voxel51.com/docs/fiftyone/user_guide/draw_labels.html#customizing-annotation-rendering\n",
    "#\n",
    "annotation_config = foua.AnnotationConfig({\n",
    "    \"font_size\": 36\n",
    "})\n",
    "\n",
    "# Render the labels\n",
    "print(\"Writing annotated images to '%s'\" % anno_dir)\n",
    "view.draw_labels(anno_dir, annotation_config=annotation_config)\n",
    "print(\"Annotation complete\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's list the output directory to verify that the annotations have been generated:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total 17456\r\n",
      "drwxr-xr-x  182 Brian  wheel   5.7K Jul 27 18:37 .\r\n",
      "drwxr-xr-x    5 Brian  wheel   160B Jul 27 15:59 ..\r\n",
      "-rw-r--r--@   1 Brian  wheel    13K Jul 27 18:37 image_0001-2.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel    41K Jul 27 15:59 image_0001.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel   197K Jul 27 18:37 image_0002.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel   5.9K Jul 27 18:37 image_0003.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel    19K Jul 27 18:37 image_0004-2.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel    33K Jul 27 15:59 image_0004.jpg\r\n",
      "-rw-r--r--    1 Brian  wheel    18K Jul 27 18:37 image_0005-2.jpg\r\n"
     ]
    }
   ],
   "source": [
    "!ls -lah /tmp/fiftyone/draw_labels/caltech101-test-anno | head"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's an example of an annotated image that was generated:\n",
    "\n",
    "![caltech101-annotated](images/draw_labels_caltech101.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cleanup\n",
    "\n",
    "You can cleanup the files generated by this recipe by running the command below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "!rm -rf /tmp/fiftyone"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
